package storage

import (
	"fmt"
	"maps"
	"math"
	"net"
	"strconv"
	"strings"
	"time"

	"gitee.com/gousing/cache/internal"
	"gitee.com/gousing/values"
	"github.com/vmihailenco/msgpack/v5"
)

func ValueToString(kind Kind, val any) (string, error) {
	if !kind.IsValid() {
		return "", ErrValueUnableToType(kind, "string")
	}
	if KindNil == kind {
		return "<nil>", nil
	}
	if val == nil {
		return "", ErrValueUnableToType("nil", "string")
	}
	switch kind {
	case KindString:
		return val.(string), nil
	case KindBool:
		if val.(bool) {
			return "1", nil
		}
		return "0", nil
	case KindInt64:
		return strconv.FormatInt(val.(int64), 10), nil
	case KindInt32:
		return strconv.Itoa(int(val.(int32))), nil
	case KindInt16:
		return strconv.Itoa(int(val.(int16))), nil
	case KindInt8:
		return strconv.Itoa(int(val.(int8))), nil
	case KindInt:
		return strconv.Itoa(val.(int)), nil
	case KindUint64:
		return strconv.FormatUint(val.(uint64), 10), nil
	case KindUint32:
		return strconv.FormatUint(uint64(val.(uint32)), 10), nil
	case KindUint16:
		return strconv.Itoa(int(val.(uint16))), nil
	case KindUint8:
		return strconv.Itoa(int(val.(uint8))), nil
	case KindUint:
		return strconv.FormatUint(uint64(val.(uint)), 10), nil
	case KindFloat64:
		return strconv.FormatFloat(val.(float64), 'f', -1, 64), nil
	case KindFloat32:
		return strconv.FormatFloat(float64(val.(float32)), 'f', -1, 32), nil
	case KindBytes:
		return string(val.([]byte)), nil
	case KindTime:
		return val.(time.Time).Format(time.RFC3339Nano), nil
	case KindDuration:
		return val.(time.Duration).String(), nil
	case KindWeekday:
		return val.(time.Weekday).String(), nil
	case KindMonth:
		return val.(time.Month).String(), nil
	case KindComplex64:
		return complex64ToString(val.(complex64)), nil
	case KindComplex128:
		return complex128ToString(val.(complex128)), nil
	case KindIP:
		return val.(net.IP).String(), nil
	case KindSerializer:
		if val, ok := val.([]byte); ok {
			var toVal string
			err := msgpack.Unmarshal(val, &toVal)
			return toVal, ErrValueUnableToType(kind, "string, unmarshal error: "+err.Error())
		}
		return "", ErrValueNotBytes
	}
	// 尝试使用 Stringer 接口转换类型为 string
	if io, ok := val.(interface{ ToString() string }); ok {
		return io.ToString(), nil
	}
	if io, ok := val.(interface{ String() string }); ok {
		return io.String(), nil
	}

	return "", ErrValueUnableToType(kind, "string")
}
func ValueToBool(kind Kind, val any) (bool, error) {
	if !kind.IsValid() {
		return false, ErrValueUnableToType(kind, "bool")
	}
	if KindNil == kind {
		return false, nil
	}
	if val == nil {
		return false, ErrValueUnableToType("nil", "bool")
	}
	switch kind {
	case KindString:
		if val, ok := val.(string); ok {
			switch val {
			case "1", "t", "T", "true", "TRUE", "True", "on", "On", "ON", "yes", "YES", "Yes":
				return true, nil
			case "0", "f", "F", "false", "FALSE", "False", "off", "Off", "OFF", "no", "NO", "No":
				return false, nil
			default:
				if internal.IsInt(val) {
					// 将字符串转INT和0比较，不为0即为true
					i64, err := strconv.ParseInt(val, 10, 64)
					if err != nil {
						return false, ErrValueUnableToType(val, "bool")
					}
					return i64 != 0, nil
				}
				if internal.IsFloat(val) {
					f64, err := strconv.ParseFloat(val, 64)
					if err != nil {
						return false, ErrValueUnableToType(val, "bool")
					}
					return f64 != 0, nil
				}
				return false, ErrValueUnableToType(val, "bool")
			}
		}
	case KindBool:
		return val.(bool), nil
	case KindInt64:
		return val.(int64) != 0, nil
	case KindInt32:
		return val.(int32) != 0, nil
	case KindInt16:
		return val.(int16) != 0, nil
	case KindInt8:
		return val.(int8) != 0, nil
	case KindInt:
		return val.(int) != 0, nil
	case KindUint64:
		return val.(uint64) != 0, nil
	case KindUint32:
		return val.(uint32) != 0, nil
	case KindUint16:
		return val.(uint16) != 0, nil
	case KindUint8:
		return val.(uint8) != 0, nil
	case KindUint:
		return val.(uint) != 0, nil
	case KindFloat64:
		return val.(float64) != 0, nil
	case KindFloat32:
		return val.(float32) != 0, nil
	case KindBytes:
		if val, ok := val.([]byte); ok {
			return len(val) > 0, nil
		}
		return false, ErrValueNotBytes
	case KindTime:
		if val, ok := val.(time.Time); ok {
			return !val.IsZero(), nil
		}
		return false, ErrValueNotTime
	case KindDuration:
		return val.(time.Duration) != 0, nil
	case KindWeekday:
		return val.(time.Weekday) != 0, nil
	case KindMonth:
		return val.(time.Month) != 0, nil
	case KindComplex64:
		return val.(complex64) != 0, nil
	case KindComplex128:
		return val.(complex128) != 0, nil
	case KindIP:
		return val.(net.IP).To16() != nil, nil
	case KindSerializer:
		if val, ok := val.([]byte); ok {
			var toVal bool
			err := msgpack.Unmarshal(val, &toVal)
			return toVal, ErrValueUnableToType(kind, "bool, unmarshal error: "+err.Error())
		}
		return false, ErrValueNotBytes
	}
	// 尝试使用 Booler 接口转换类型为 bool
	if io, ok := val.(interface{ ToBool() bool }); ok {
		return io.ToBool(), nil
	}
	if io, ok := val.(interface{ Bool() bool }); ok {
		return io.Bool(), nil
	}
	return false, ErrValueUnableToType(kind, "bool")
}
func ValueToInt64(kind Kind, val any) (int64, error) {
	if !kind.IsValid() {
		return 0, ErrValueUnableToType(kind, "int64")
	}
	if KindNil == kind {
		return 0, nil
	}
	if val == nil {
		return 0, ErrValueUnableToType("nil", "int64")
	}

	switch val := val.(type) {
	case string:
		if val == "" {
			return 0, nil
		}
		return strconv.ParseInt(val, 10, 64)
	case int64:
		return val, nil
	case int32:
		return int64(val), nil
	case int16:
		return int64(val), nil
	case int8:
		return int64(val), nil
	case int:
		return int64(val), nil
	case uint64:
		if val > math.MaxInt64 {
			return math.MaxInt64, ErrValueToNumberOutOfRange("int64", val)
		}
		return int64(val), nil
	case uint32:
		return int64(val), nil
	case uint16:
		return int64(val), nil
	case uint8:
		return int64(val), nil
	case uint:
		return int64(val), nil
	case float64:
		if val > math.MaxInt64 || val < math.MinInt64 {
			return 0, ErrValueToNumberOutOfRange("int64", val)
		}
		return int64(val), nil
	case float32:
		f := float64(val)
		if f > math.MaxInt64 || f < math.MinInt64 {
			return 0, ErrValueToNumberOutOfRange("int64", val)
		}
		return int64(f), nil
	}

	switch kind {
	case KindString:
		return strconv.ParseInt(val.(string), 10, 64)
	case KindBool:
		if val.(bool) {
			return 1, nil
		}
		return 0, nil
	case KindInt64:
		return val.(int64), nil
	case KindInt32:
		return int64(val.(int32)), nil
	case KindInt16:
		return int64(val.(int16)), nil
	case KindInt8:
		return int64(val.(int8)), nil
	case KindInt:
		return int64(val.(int)), nil
	case KindUint64:
		v := val.(uint64)
		if v > math.MaxInt64 {
			return math.MaxInt64, ErrValueToNumberOutOfRange("int64", v)
		}
		return int64(v), nil
	case KindUint32:
		return int64(val.(uint32)), nil
	case KindUint16:
		return int64(val.(uint16)), nil
	case KindUint8:
		return int64(val.(uint8)), nil
	case KindUint:
		return int64(val.(uint)), nil
	case KindFloat64:
		f := val.(float64)
		if f > math.MaxInt64 || f < math.MinInt64 {
			return 0, ErrValueToNumberOutOfRange("int64", f)
		}
		return int64(f), nil
	case KindFloat32:
		f := val.(float32)
		if f > math.MaxInt64 || f < math.MinInt64 {
			return 0, ErrValueToNumberOutOfRange("int64", f)
		}
		return int64(f), nil
	case KindTime:
		return val.(time.Time).Unix(), nil
	case KindDuration:
		return int64(val.(time.Duration)), nil
	case KindWeekday:
		return int64(val.(time.Weekday)), nil
	case KindMonth:
		return int64(val.(time.Month)), nil
	case KindSerializer:
		var toVal int64
		err := msgpack.Unmarshal(val.([]byte), &toVal)
		return toVal, ErrValueUnableToType(kind, "int64, unmarshal error: "+err.Error())
	}
	// 尝试使用 IntX/UintX/FloatX 接口转换类型为 int64
	switch val := val.(type) {
	case interface{ Int64() int64 }:
		return val.Int64(), nil
	case interface{ Int32() int32 }:
		return int64(val.Int32()), nil
	case interface{ Int16() int16 }:
		return int64(val.Int16()), nil
	case interface{ Int8() int8 }:
		return int64(val.Int8()), nil
	case interface{ Int() int }:
		return int64(val.Int()), nil
	case interface{ Uint64() uint64 }:
		v := val.Uint64()
		if v > math.MaxInt64 {
			return math.MaxInt64, ErrValueToNumberOutOfRange("int64", v)
		}
		return int64(v), nil
	case interface{ Uint32() uint32 }:
		return int64(val.Uint32()), nil
	case interface{ Uint16() uint16 }:
		return int64(val.Uint16()), nil
	case interface{ Uint8() uint8 }:
		return int64(val.Uint8()), nil
	case interface{ Uint() uint }:
		v := val.Uint()
		if v > math.MaxInt64 {
			return math.MaxInt64, ErrValueToNumberOutOfRange("int64", v)
		}
		return int64(v), nil
	case interface{ Float() float64 }:
		f := val.Float()
		if f > math.MaxInt64 || f < math.MinInt64 {
			return 0, ErrValueToNumberOutOfRange("int64", f)
		}
		return int64(f), nil
	case interface{ Float64() float64 }:
		f := val.Float64()
		if f > math.MaxInt64 || f < math.MinInt64 {
			return 0, ErrValueToNumberOutOfRange("int64", f)
		}
		return int64(f), nil
	case interface{ Float32() float32 }:
		f := val.Float32()
		if f > math.MaxInt64 || f < math.MinInt64 {
			return 0, ErrValueToNumberOutOfRange("int64", f)
		}
		return int64(f), nil
	}

	return 0, ErrValueUnableToType(kind, "int64")
}
func ValueToInt32(kind Kind, val any) (int32, error) {
	i64, err := ValueToInt64(kind, val)
	if err != nil {
		return 0, ErrValueUnableToType(kind, "int32")
	}
	if i64 > math.MaxInt32 || i64 < math.MinInt32 {
		return 0, ErrValueToNumberOutOfRange("int32", i64)
	}
	return int32(i64), nil
}
func ValueToInt16(kind Kind, val any) (int16, error) {
	i64, err := ValueToInt64(kind, val)
	if err != nil {
		return 0, ErrValueUnableToType(kind, "int16")
	}
	if i64 > math.MaxInt16 || i64 < math.MinInt16 {
		return 0, ErrValueToNumberOutOfRange("int16", i64)
	}
	return int16(i64), nil
}
func ValueToInt8(kind Kind, val any) (int8, error) {
	i64, err := ValueToInt64(kind, val)
	if err != nil {
		return 0, ErrValueUnableToType(kind, "int8")
	}
	if i64 > math.MaxInt8 || i64 < math.MinInt8 {
		return 0, ErrValueToNumberOutOfRange("int8", i64)
	}
	return int8(i64), nil
}
func ValueToInt(kind Kind, val any) (int, error) {
	i64, err := ValueToInt64(kind, val)
	if err != nil {
		return 0, ErrValueUnableToType(kind, "int")
	}
	if i64 > math.MaxInt || i64 < math.MinInt {
		return 0, ErrValueToNumberOutOfRange("int", i64)
	}
	return int(i64), nil
}
func ValueToUint64(kind Kind, val any) (uint64, error) {
	if !kind.IsValid() {
		return 0, ErrValueUnableToType(kind, "uint64")
	}
	if KindNil == kind {
		return 0, nil
	}
	if val == nil {
		return 0, ErrValueUnableToType(kind, "uint64")
	}
	switch kind {
	case KindString:
		return strconv.ParseUint(val.(string), 10, 64)
	case KindBool:
		if val.(bool) {
			return 1, nil
		}
		return 0, nil
	case KindInt64:
		intVal := val.(int64)
		if intVal < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", intVal)
		}
		return uint64(intVal), nil
	case KindInt32:
		intVal := val.(int32)
		if intVal < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", intVal)
		}
		return uint64(intVal), nil
	case KindInt16:
		intVal := val.(int16)
		if intVal < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", intVal)
		}
		return uint64(intVal), nil
	case KindInt8:
		intVal := val.(int8)
		if intVal < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", intVal)
		}
		return uint64(intVal), nil
	case KindInt:
		intVal := val.(int)
		if intVal < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", intVal)
		}
		return uint64(intVal), nil
	case KindUint64:
		return val.(uint64), nil
	case KindUint32:
		return uint64(val.(uint32)), nil
	case KindUint16:
		return uint64(val.(uint16)), nil
	case KindUint8:
		return uint64(val.(uint8)), nil
	case KindUint:
		return uint64(val.(uint)), nil
	case KindFloat64:
		f := val.(float64)
		if f > math.MaxUint64 {
			return math.MaxUint64, ErrValueToNumberOutOfRange("uint64", f)
		}
		if f < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", f)
		}
		return uint64(f), nil
	case KindFloat32:
		f := val.(float32)
		if f > math.MaxUint64 {
			return math.MaxUint64, ErrValueToNumberOutOfRange("uint64", f)
		}
		if f < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", f)
		}
		return uint64(f), nil
	case KindDuration:
		vs := val.(time.Duration)
		if vs < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", int64(vs))
		}
		return uint64(vs), nil
	case KindWeekday:
		vs := val.(time.Weekday)
		if vs < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", int64(vs))
		}
		return uint64(vs), nil
	case KindMonth:
		vs := val.(time.Month)
		if vs < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", int64(vs))
		}
		return uint64(vs), nil
	case KindSerializer:
		var toVal uint64
		err := msgpack.Unmarshal(val.([]byte), &toVal)
		return toVal, ErrValueUnableToType(kind, "uint64, unmarshal error: "+err.Error())
	}

	// 尝试使用 IntX/UintX/FloatX 接口转换类型为 uint64
	switch val := val.(type) {
	case interface{ Int64() int64 }:
		iv := val.Int64()
		if iv < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", iv)
		}
		return uint64(iv), nil
	case interface{ Int32() int32 }:
		iv := val.Int32()
		if iv < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", iv)
		}
		return uint64(iv), nil
	case interface{ Int16() int16 }:
		iv := val.Int16()
		if iv < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", iv)
		}
		return uint64(iv), nil
	case interface{ Int8() int8 }:
		iv := val.Int8()
		if iv < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", iv)
		}
		return uint64(iv), nil
	case interface{ Int() int }:
		iv := val.Int()
		if iv < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", iv)
		}
		return uint64(iv), nil
	case interface{ Uint64() uint64 }:
		return val.Uint64(), nil
	case interface{ Uint32() uint32 }:
		return uint64(val.Uint32()), nil
	case interface{ Uint16() uint16 }:
		return uint64(val.Uint16()), nil
	case interface{ Uint8() uint8 }:
		return uint64(val.Uint8()), nil
	case interface{ Uint() uint }:
		return uint64(val.Uint()), nil
	case interface{ Float() float64 }:
		f := val.Float()
		if f > math.MaxUint64 {
			return math.MaxUint64, ErrValueToNumberOutOfRange("uint64", f)
		}
		if f < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", f)
		}
		return uint64(f), nil
	case interface{ Float64() float64 }:
		f := val.Float64()
		if f > math.MaxUint64 {
			return math.MaxUint64, ErrValueToNumberOutOfRange("uint64", f)
		}
		if f < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", f)
		}
		return uint64(f), nil
	case interface{ Float32() float32 }:
		f := val.Float32()
		if f > math.MaxUint64 {
			return math.MaxUint64, ErrValueToNumberOutOfRange("uint64", f)
		}
		if f < 0 {
			return 0, ErrValueToNumberOutOfRange("uint64", f)
		}
		return uint64(f), nil
	}
	return 0, ErrValueUnableToType(kind, "uint64")
}
func ValueToUint32(kind Kind, val any) (uint32, error) {
	u64, err := ValueToUint64(kind, val)
	if err != nil {
		return 0, ErrValueUnableToType(kind, "uint32")
	}
	if u64 > math.MaxUint32 {
		return math.MaxUint32, ErrValueToNumberOutOfRange("uint32", u64)
	}
	return uint32(u64), nil
}
func ValueToUint16(kind Kind, val any) (uint16, error) {
	u64, err := ValueToUint64(kind, val)
	if err != nil {
		return 0, ErrValueUnableToType(kind, "uint16")
	}
	if u64 > math.MaxUint16 {
		return math.MaxUint16, ErrValueToNumberOutOfRange("uint16", u64)
	}
	return uint16(u64), nil
}
func ValueToUint8(kind Kind, val any) (uint8, error) {
	u64, err := ValueToUint64(kind, val)
	if err != nil {
		return 0, ErrValueUnableToType(kind, "uint8")
	}
	if u64 > math.MaxUint8 {
		return math.MaxUint8, ErrValueToNumberOutOfRange("uint8", u64)
	}
	return uint8(u64), nil
}
func ValueToUint(kind Kind, val any) (uint, error) {
	u64, err := ValueToUint64(kind, val)
	if err != nil {
		return 0, ErrValueUnableToType(kind, "uint")
	}
	if u64 > math.MaxUint {
		return math.MaxUint, ErrValueToNumberOutOfRange("uint", u64)
	}
	return uint(u64), nil
}
func ValueToFloat64(kind Kind, val any) (float64, error) {
	if !kind.IsValid() {
		return 0, ErrValueUnableToType(kind, "float64")
	}
	if KindNil == kind {
		return 0, nil
	}
	if val == nil {
		return 0, ErrValueUnableToType("nil", "float64")
	}
	switch kind {
	case KindString:
		return strconv.ParseFloat(val.(string), 64)
	case KindBool:
		if val.(bool) {
			return 1, nil
		}
		return 0, nil
	case KindInt64:
		return float64(val.(int64)), nil
	case KindInt32:
		return float64(val.(int32)), nil
	case KindInt16:
		return float64(val.(int16)), nil
	case KindInt8:
		return float64(val.(int8)), nil
	case KindInt:
		return float64(val.(int)), nil
	case KindUint64:
		return float64(val.(uint64)), nil
	case KindUint32:
		return float64(val.(uint32)), nil
	case KindUint16:
		return float64(val.(uint16)), nil
	case KindUint8:
		return float64(val.(uint8)), nil
	case KindUint:
		return float64(val.(uint)), nil
	case KindFloat64:
		return val.(float64), nil
	case KindFloat32:
		return float64(val.(float32)), nil
	case KindBytes:
		//return 0, fmt.Errorf("unknown %s type convert to float64", "[]byte")
	case KindTime:
		if vs, ok := val.(time.Time); ok {
			return float64(vs.UnixNano()), nil
		}
		return 0, ErrValueUnableToType(KindTime, "float64")
	case KindDuration:
		return float64(val.(time.Duration)), nil
	case KindWeekday:
		return float64(val.(time.Weekday)), nil
	case KindMonth:
		return float64(val.(time.Month)), nil
	case KindSerializer:
		var toVal float64
		err := msgpack.Unmarshal(val.([]byte), &toVal)
		return toVal, ErrValueUnableToType(kind, "float64, unmarshal error: "+err.Error())
	}
	return 0, ErrValueUnableToType(kind, "float64")
}
func ValueToFloat32(kind Kind, val any) (float32, error) {
	if !kind.IsValid() {
		return 0, ErrValueUnableToType(kind, "float32")
	}
	if KindNil == kind {
		return 0, nil
	}
	if val == nil {
		return 0, ErrValueUnableToType("nil", "float32")
	}
	switch kind {
	case KindString:
		f, err := strconv.ParseFloat(val.(string), 64)
		if err != nil {
			return 0, err
		}
		return float32(f), nil
	case KindBool:
		if val.(bool) {
			return 1, nil
		}
		return 0, nil
	case KindInt64:
		return float32(val.(int64)), nil
	case KindInt32:
		return float32(val.(int32)), nil
	case KindInt16:
		return float32(val.(int16)), nil
	case KindInt8:
		return float32(val.(int8)), nil
	case KindInt:
		return float32(val.(int)), nil
	case KindUint64:
		return float32(val.(uint64)), nil
	case KindUint32:
		return float32(val.(uint32)), nil
	case KindUint16:
		return float32(val.(uint16)), nil
	case KindUint8:
		return float32(val.(uint8)), nil
	case KindUint:
		return float32(val.(uint)), nil
	case KindFloat64:
		return float32(val.(float64)), nil
	case KindFloat32:
		return val.(float32), nil
	case KindTime:
		if vs, ok := val.(time.Time); ok {
			return float32(vs.UnixNano()), nil
		}
		return 0, ErrValueUnableToType(KindTime, "float32")
	case KindDuration:
		return float32(val.(time.Duration)), nil
	case KindWeekday:
		return float32(val.(time.Weekday)), nil
	case KindMonth:
		return float32(val.(time.Month)), nil
	case KindComplex64:
		//return 0, fmt.Errorf("unknown %s type convert to float32", "complex64")
	case KindComplex128:
		//return 0, fmt.Errorf("unknown %s type convert to float32", "complex128")
	case KindIP:
		//return 0, fmt.Errorf("unknown %s type convert to float32", "net.IP")
	case KindBytes, KindSerializer:
		var toVal float32
		err := msgpack.Unmarshal(val.([]byte), &toVal)
		if err != nil {
			return 0, ErrValueUnableToType(kind, "float32, unmarshal error: "+err.Error())
		}
		return toVal, nil
	}
	return 0, ErrValueUnableToType(kind, "float32")
}
func ValueToTime(kind Kind, val any) (time.Time, error) {
	if !kind.IsValid() {
		return time.Time{}, ErrValueUnableToType(kind, "time.Time")
	}
	if val == nil || KindNil == kind {
		return time.Time{}, ErrValueUnableToType("nil", "time.Time")
	}
	switch kind {
	case KindTime:
		if vs, ok := val.(time.Time); ok {
			if vs.IsZero() {
				return vs, nil
			}
			if vs.Location() == nil {
				return vs.In(time.Local), nil
			}
			return vs, nil
		}
		return time.Time{}, ErrValueUnableToType(fmt.Sprintf("%T", val), "time.Time")
	case KindString:
		if to, err := values.ParseTimeAutoLayout(val.(string), time.Local); err == nil {
			return to, nil
		} else {
			return time.Time{}, ErrValueUnableToType("string", "time.Time, error: "+err.Error())
		}
	case KindInt, KindInt64, KindInt32, KindInt16, KindInt8,
		KindUint, KindUint64, KindUint32, KindUint16, KindUint8:
		vs, err := ValueToInt64(kind, val)
		// 数值类型当做秒级时间戳处理
		if err != nil {
			return time.Time{}, ErrValueUnableToType(kind, "time.Time")
		}
		return time.Unix(int64(vs), 0).In(time.Local), nil
	case KindBytes, KindSerializer:
		var scan time.Time
		err := msgpack.Unmarshal(val.([]byte), &scan)
		if err != nil {
			return time.Time{}, ErrValueUnableToType(kind, "time.Time, unmarshal error: "+err.Error())
		}
		return scan, nil
	}
	// 尝试使用 ToTime 接口转换类型为 time.Month
	if io, ok := val.(interface{ ToTime() time.Time }); ok {
		return io.ToTime(), nil
	}
	if io, ok := val.(interface{ Time() time.Time }); ok {
		return io.Time(), nil
	}
	return time.Time{}, ErrValueUnableToType(kind, "time.Time")
}
func ValueToDuration(kind Kind, val any) (time.Duration, error) {
	if !kind.IsValid() {
		return 0, ErrValueUnableToType(kind, "time.Duration")
	}
	if KindNil == kind {
		return 0, nil
	}
	if val == nil {
		return 0, ErrValueUnableToType("nil", "time.Duration")
	}
	switch kind {
	case KindTime:
		return time.Duration(val.(time.Time).UnixNano()) * time.Nanosecond, nil
	case KindString:
		vs := val.(string)
		if strings.ContainsAny(vs, "nsuµmh") {
			return time.ParseDuration(vs)
		} else if internal.IsInt(vs) {
			return time.ParseDuration(vs + "ns")
		}
	case KindInt, KindInt64, KindInt32, KindInt16, KindInt8,
		KindUint, KindUint64, KindUint32, KindUint16, KindUint8,
		KindFloat32, KindFloat64:
		vs, err := ValueToInt64(kind, val)
		if err != nil {
			return 0, ErrValueUnableToType(kind, "time.Duration")
		}
		return time.Duration(vs), nil
	case KindDuration:
		return val.(time.Duration), nil
	case KindSerializer:
		var scan time.Duration
		err := msgpack.Unmarshal(val.([]byte), &scan)
		if err != nil {
			return 0, ErrValueUnableToType(kind, "time.Duration, unmarshal error: "+err.Error())
		}
		return scan, nil
	}
	// 尝试使用 ToDuration 接口转换类型为 time.Duration
	if io, ok := val.(interface{ ToDuration() time.Duration }); ok {
		return io.ToDuration(), nil
	}
	if io, ok := val.(interface{ Duration() time.Duration }); ok {
		return io.Duration(), nil
	}
	return 0, ErrValueUnableToType(kind, "time.Duration")
}
func ValueToMonth(kind Kind, val any) (time.Month, error) {
	if !kind.IsValid() {
		return 0, ErrValueUnableToType(kind, "time.Month")
	}
	if val == nil || KindNil == kind {
		return 0, ErrValueUnableToType("nil", "time.Month")
	}
	switch kind {
	case KindTime:
		return val.(time.Time).Month(), nil
	case KindString:
		vs := val.(string)
		switch strings.ToLower(vs) {
		case "january", "jan", "1", "1月", "一月":
			return time.January, nil
		case "february", "feb", "2", "2月", "二月":
			return time.February, nil
		case "march", "mar", "3", "3月", "三月":
			return time.March, nil
		case "april", "apr", "41", "4月", "四月":
			return time.April, nil
		case "may", "5", "5月", "五月":
			return time.May, nil
		case "june", "jun", "6", "6月", "六月":
			return time.June, nil
		case "july", "jul", "7", "7月", "七月":
			return time.July, nil
		case "august", "aug", "8", "8月", "八月":
			return time.August, nil
		case "september", "sep", "9", "9月", "九月":
			return time.September, nil
		case "october", "oct", "10", "10月", "十月":
			return time.October, nil
		case "november", "nov", "11", "11月", "十一月":
			return time.November, nil
		case "december", "dec", "12", "12月", "十二月":
			return time.December, nil
		}
	case KindInt, KindInt64, KindInt32, KindInt16, KindInt8,
		KindUint, KindUint64, KindUint32, KindUint16, KindUint8,
		KindFloat32, KindFloat64:
		vs, err := ValueToUint8(kind, val)
		if err != nil {
			return 0, ErrValueUnableToType(kind, "time.Month")
		}
		if vs >= 1 && vs <= 12 {
			return time.Month(int(vs)), nil
		}
	case KindMonth:
		return val.(time.Month), nil
	}
	// 尝试使用 ToMonth 接口转换类型为 time.Month
	if io, ok := val.(interface{ ToMonth() time.Month }); ok {
		return io.ToMonth(), nil
	}
	if io, ok := val.(interface{ Month() time.Month }); ok {
		return io.Month(), nil
	}
	return 0, ErrValueUnableToType(kind, "time.Month")
}
func ValueToWeekday(kind Kind, val any) (time.Weekday, error) {
	if !kind.IsValid() {
		return 0, ErrValueUnableToType(kind, "time.Weekday")
	}
	if val == nil || KindNil == kind {
		return 0, ErrValueUnableToType("nil", "time.Weekday")
	}
	switch kind {
	case KindTime:
		return val.(time.Time).Weekday(), nil
	case KindString:
		vs := val.(string)
		switch strings.ToLower(vs) {
		case "sunday", "sun", "0", "周7", "周日", "星期日", "星期天":
			return time.Sunday, nil
		case "monday", "mon", "1", "周1", "周一", "星期一":
			return time.Monday, nil
		case "tuesday", "tue", "2", "周2", "周二", "星期二":
			return time.Tuesday, nil
		case "wednesday", "wed", "3", "周3", "周三", "星期三":
			return time.Wednesday, nil
		case "thursday", "thu", "4", "周4", "周四", "星期四":
			return time.Thursday, nil
		case "friday", "fri", "5", "周5", "周五", "星期五":
			return time.Friday, nil
		case "saturday", "sat", "6", "周6", "周六", "星期六":
			return time.Saturday, nil
		}
	case KindInt, KindInt64, KindInt32, KindInt16, KindInt8,
		KindUint, KindUint64, KindUint32, KindUint16, KindUint8,
		KindFloat32, KindFloat64:
		vs, err := ValueToUint8(kind, val)
		if err != nil {
			return 0, ErrValueUnableToType(kind, "time.Weekday")
		}
		if vs <= 6 {
			return time.Weekday(int(vs)), nil
		}
	case KindWeekday:
		return val.(time.Weekday), nil
	}
	// 尝试使用 ToWeekday 接口转换类型为 time.Weekday
	if io, ok := val.(interface{ ToWeekday() time.Weekday }); ok {
		return io.ToWeekday(), nil
	}
	if io, ok := val.(interface{ Weekday() time.Weekday }); ok {
		return io.Weekday(), nil
	}
	return 0, ErrValueUnableToType(kind, "time.Weekday")
}
func ValueToComplex64(kind Kind, val any) (complex64, error) {
	if !kind.IsValid() {
		return 0, ErrValueUnableToType(kind, "complex64")
	}
	if val == nil || KindNil == kind {
		return 0, ErrValueUnableToType("nil", "complex64")
	}
	switch kind {
	case KindString:
		return stringToComplex64(val.(string))
	case KindComplex64:
		return val.(complex64), nil
	case KindComplex128:
		// 从 complex128 转为 complex64 有精度降低风险
		return complex64(val.(complex128)), nil
	case KindSerializer:
		var scan complex64
		err := msgpack.Unmarshal(val.([]byte), &scan)
		if err != nil {
			return 0, ErrValueUnableToType(kind, "complex64, unmarshal error: "+err.Error())
		}
		return scan, nil
	}
	return 0, ErrValueUnableToType(kind, "complex64")
}
func ValueToComplex128(kind Kind, val any) (complex128, error) {
	if !kind.IsValid() {
		return 0, ErrValueUnableToType(kind, "complex128")
	}
	if val == nil || KindNil == kind {
		return 0, ErrValueUnableToType("nil", "complex128")
	}
	switch kind {
	case KindString:
		return stringToComplex128(val.(string))
	case KindComplex64:
		return complex128(val.(complex64)), nil
	case KindComplex128:
		return val.(complex128), nil
	case KindSerializer:
		var scan complex128
		err := msgpack.Unmarshal(val.([]byte), &scan)
		if err != nil {
			return 0, ErrValueUnableToType(kind, "complex128, unmarshal error: "+err.Error())
		}
		return scan, nil
	}
	return 0, ErrValueUnableToType(kind, "complex128")
}

func ValueToIP(kind Kind, val any) (net.IP, error) {
	if !kind.IsValid() {
		return net.IP{}, ErrValueUnableToType(kind, "net.IP")
	}
	if val == nil || KindNil == kind {
		return net.IP{}, ErrValueUnableToType("nil", "net.IP")
	}
	switch kind {
	case KindIP:
		return val.(net.IP), nil
	case KindString:
		return stringToIP(val.(string))
	case KindInt, KindInt64, KindInt32, KindInt16, KindInt8,
		KindUint, KindUint64, KindUint32, KindUint16, KindUint8:
		vs, err := ValueToInt64(kind, val)
		if err != nil {
			return net.IP{}, ErrValueUnableToType(kind, "net.IP")
		}
		return intToIP(vs)
	case KindSerializer:
		var scan net.IP
		err := msgpack.Unmarshal(val.([]byte), &scan)
		if err != nil {
			return net.IP{}, ErrValueUnableToType(kind, "net.IP, unmarshal error: "+err.Error())
		}
		return scan, nil
	}
	return nil, ErrValueUnableToType(kind, "net.IP")
}

func stringToIP(val string) (net.IP, error) {
	if len(val) == 0 {
		return net.IP{}, ErrValueUnableToType("string", "net.IP")
	}
	if strings.Count(val, ".") == 3 {
		// 尝试使用 net.ParseIP 方法解析字符串为 IP 地址
		ip := net.ParseIP(val)
		if ip != nil {
			return ip, nil
		}
	} else if internal.IsUint(val) {
		// 尝试将字符串转换为数字类型的 IP 地址 比如: "3232235521" => "192.168.0.1"
		ipInt, err := strconv.ParseInt(val, 10, 64)
		if err != nil {
			return net.IP{}, ErrValueUnableToType("string", "net.IP")
		}
		return intToIP(ipInt)
	}
	return net.IP{}, ErrValueUnableToType("string", "net.IP")
}

func intToIP[T TypeInt | TypeUint](val T) (net.IP, error) {
	if val > 0 {
		ipInt := int64(val)
		ipStr := fmt.Sprintf("%d.%d.%d.%d",
			byte(ipInt>>24), byte(ipInt>>16), byte(ipInt>>8), byte(ipInt))
		ip := net.ParseIP(ipStr)
		if ip != nil {
			return ip, nil
		}
	}
	return net.IP{}, ErrValueUnableToType("int64", "net.IP")
}

func ValueToBytes(kind Kind, val any) ([]byte, error) {
	if !kind.IsValid() {
		return []byte{}, ErrValueUnableToType(kind, "[]byte")
	}
	if KindNil == kind {
		return []byte{}, nil
	}
	if val == nil {
		return []byte{}, ErrValueUnableToType("nil", "[]byte")
	}
	switch kind {
	case KindString:
		return []byte(val.(string)), nil
	case KindBytes, KindSerializer:
		if data, ok := val.([]byte); ok {
			buf := make([]byte, len(data))
			copy(buf, data)
			return buf, nil
		}
		return []byte{}, ErrValueNotBytes
	default:
		switch val := val.(type) {
		case []byte:
			buf := make([]byte, len(val))
			copy(buf, val)
			return buf, nil
		case interface{ ToBytes() []byte }:
			return val.ToBytes(), nil
		case interface{ Bytes() []byte }:
			return val.Bytes(), nil
		default:
			bytes, err := msgpack.Marshal(val)
			if err != nil {
				return []byte{}, ErrValueUnableToType(kind, "[]byte, marshal error: "+err.Error())
			}
			return bytes, nil
		}
	}
}
func ValueToSetStringMap(kind Kind, val any) (map[string]struct{}, error) {
	if !kind.IsValid() {
		return map[string]struct{}{}, ErrValueUnableToType(kind, "map[string]struct{}")
	}
	if KindNil == kind {
		return map[string]struct{}{}, nil
	}
	if val == nil {
		return map[string]struct{}{}, ErrValueUnableToType("nil", "map[string]struct{}")
	}
	if val, ok := val.(map[string]struct{}); ok {
		return val, nil
	}
	switch kind {
	case KindSetString:
		// from memcache 返回字符串集合, 直接返回副本即可
		if data, ok := val.(map[string]struct{}); ok {
			buf := make(map[string]struct{}, len(data))
			maps.Copy(buf, data)
			return buf, nil
		}
		// from redis 返回字符串切片, 需要转换为集合类型
		if data, ok := val.([]string); ok {
			buf := make(map[string]struct{}, len(data))
			for _, v := range data {
				buf[v] = struct{}{}
			}
			return buf, nil
		}
		return map[string]struct{}{}, ErrValueNotSetString
	case KindSetInt:
		// from memcache 返回整数集合, 转换为字符串集合类型
		if data, ok := val.(map[int64]struct{}); ok {
			buf := make(map[string]struct{}, len(data))
			for k, v := range data {
				buf[strconv.FormatInt(k, 10)] = v
			}
			return buf, nil
		}
		// from redis 返回字符串切片, 转换为字符串集合类型
		if data, ok := val.([]string); ok {
			buf := make(map[string]struct{}, len(data))
			for _, v := range data {
				buf[v] = struct{}{}
			}
			return buf, nil
		}
		return map[string]struct{}{}, ErrValueNotSetString
	case KindSerializer:
		var scan map[string]struct{}
		err := msgpack.Unmarshal(val.([]byte), &scan)
		if err != nil {
			return map[string]struct{}{}, ErrValueUnableToType(kind, "map[string]struct{}, unmarshal error: "+err.Error())
		}
		return scan, nil
	}
	return map[string]struct{}{}, ErrValueUnableToType(kind, "map[string]struct{}")
}
func ValueToSetIntMap(kind Kind, val any) (map[int64]struct{}, error) {
	if !kind.IsValid() {
		return map[int64]struct{}{}, ErrValueUnableToType(kind, "map[int64]struct{}")
	}
	if KindNil == kind {
		return map[int64]struct{}{}, nil
	}
	if val == nil {
		return map[int64]struct{}{}, ErrValueUnableToType("nil", "map[int64]struct{}")
	}
	if val, ok := val.(map[int64]struct{}); ok {
		return val, nil
	}
	switch kind {
	case KindSetString:
		// from memcache 返回字符串集合类型转换为整数集合类型
		if data, ok := val.(map[string]struct{}); ok {
			buf := make(map[int64]struct{}, len(data))
			for v := range data {
				if k64, err := strconv.ParseInt(v, 10, 64); err == nil {
					buf[k64] = struct{}{}
				} else {
					return map[int64]struct{}{}, ErrValueUnableToType(kind, "map[int64]struct{}")
				}
			}
			return buf, nil
		}
		// from redis 返回字符串切片类型转换为整数集合类型
		if data, ok := val.([]string); ok {
			buf := make(map[int64]struct{}, len(data))
			for _, v := range data {
				if k64, err := strconv.ParseInt(v, 10, 64); err == nil {
					buf[k64] = struct{}{}
				} else {
					return map[int64]struct{}{}, ErrValueUnableToType(kind, "map[int64]struct{}")
				}
			}
			return buf, nil
		}
		return map[int64]struct{}{}, ErrValueNotSetString
	case KindSetInt:
		// from memcache 返回整数集合, 返回副本即可
		if data, ok := val.(map[int64]struct{}); ok {
			buf := make(map[int64]struct{}, len(data))
			maps.Copy(buf, data)
			return buf, nil
		}
		// from redis 返回字符串切片, 转为 int64 map 集合
		if data, ok := val.([]string); ok {
			buf := make(map[int64]struct{}, len(data))
			for _, v := range data {
				if k64, err := strconv.ParseInt(v, 10, 64); err == nil {
					buf[k64] = struct{}{}
				} else {
					return map[int64]struct{}{}, ErrValueUnableToType(kind, "map[int64]struct{}")
				}
			}
			return buf, nil
		}
		return map[int64]struct{}{}, ErrValueNotSetString
	case KindSerializer:
		var scan map[int64]struct{}
		err := msgpack.Unmarshal(val.([]byte), &scan)
		if err != nil {
			return map[int64]struct{}{}, ErrValueUnableToType(kind, "map[int64]struct{}, unmarshal error: "+err.Error())
		}
		return scan, nil
	}

	return map[int64]struct{}{}, ErrValueUnableToType(kind, "map[int64]struct{}")
}

// toSetStringSlice 将字符串集合类型转换为字符串切片。
func ValueToSetStringSlice(kind Kind, val any) ([]string, error) {
	if !kind.IsValid() {
		return []string{}, ErrValueUnableToType(kind, "[]string")
	}
	if KindNil == kind {
		return []string{}, nil
	}
	if val == nil {
		return []string{}, ErrValueUnableToType("nil", "[]string")
	}
	if val, ok := val.([]string); ok {
		return val, nil
	}
	switch kind {
	case KindSetString:
		// from memcache 集合返回字符串Map，直接转为切片即可
		if data, ok := val.(map[string]struct{}); ok {
			buf := make([]string, 0, len(data))
			for v := range data {
				buf = append(buf, v)
			}
			return buf, nil
		}
		// from redis 集合返回字符串切片，直接返回即可
		if data, ok := val.([]string); ok {
			return data, nil
		}
		return []string{}, ErrValueNotSetInt
	case KindSetInt:
		// from memcache 集合返回整数Map，需要转换为字符串切片
		if data, ok := val.(map[int64]struct{}); ok {
			buf := make([]string, 0, len(data))
			for v := range data {
				buf = append(buf, strconv.FormatInt(v, 10))
			}
			return buf, nil
		}
		// from redis 集合返回字符串切片，直接返回即可
		if data, ok := val.([]string); ok {
			return data, nil
		}
		return []string{}, ErrValueNotSetInt
	case KindSerializer:
		var scan []string
		err := msgpack.Unmarshal(val.([]byte), &scan)
		if err != nil {
			return []string{}, ErrValueUnableToType(kind, "[]string, unmarshal error: "+err.Error())
		}
		return scan, nil
	}
	return []string{}, ErrValueUnableToType(kind, "[]string")
}

// toSetIntSlice 将整数集合类型转换为整数切片。
func ValueToSetIntSlice(kind Kind, val any) ([]int64, error) {
	if !kind.IsValid() {
		return []int64{}, ErrValueUnableToType(kind, "[]int64")
	}
	if KindNil == kind {
		return []int64{}, nil
	}
	if val == nil {
		return []int64{}, ErrValueUnableToType("nil", "[]int64")
	}
	if val, ok := val.([]int64); ok {
		return val, nil
	}
	switch kind {
	case KindSetString:
		// from memcache
		if data, ok := val.(map[string]struct{}); ok {
			buf := make([]int64, 0, len(data))
			for v := range data {
				if v, err := strconv.ParseInt(v, 10, 64); nil == err {
					buf = append(buf, v)
				} else {
					return []int64{}, ErrValueUnableToType(kind, "[]int64, error: "+err.Error())
				}
			}
			return buf, nil
		}
		// from redis 集合返回字符串切片，需要转换为整数切片
		if data, ok := val.([]string); ok {
			buf := make([]int64, 0, len(data))
			for _, v := range data {
				if v, err := strconv.ParseInt(v, 10, 64); nil == err {
					buf = append(buf, v)
				} else {
					return []int64{}, ErrValueUnableToType(kind, "[]int64, error: "+err.Error())
				}
			}
			return buf, nil
		}
		return []int64{}, ErrValueNotSetString
	case KindSetInt:
		// from memcache
		if data, ok := val.(map[int64]struct{}); ok {
			buf := make([]int64, 0, len(data))
			for v := range data {
				buf = append(buf, v)
			}
			return buf, nil
		}
		// from redis 集合返回字符串切片，需要转换为整数切片
		if data, ok := val.([]string); ok {
			buf := make([]int64, 0, len(data))
			for _, v := range data {
				if v, err := strconv.ParseInt(v, 10, 64); nil == err {
					buf = append(buf, v)
				} else {
					return []int64{}, ErrValueUnableToType(kind, "[]int64, error: "+err.Error())
				}
			}
			return buf, nil
		}
		return []int64{}, ErrValueNotSetString
	case KindSerializer:
		var scan []int64
		err := msgpack.Unmarshal(val.([]byte), &scan)
		if err != nil {
			return []int64{}, ErrValueUnableToType(kind, "[]int64, unmarshal error: "+err.Error())
		}
		return scan, nil
	}
	return []int64{}, ErrValueUnableToType(kind, "[]int64")
}

// Complex 复数和字符串之间的转换工具函数

func complex128ToString(c complex128) string {
	return fmt.Sprintf("%v", c) // 输出如: (3.14+2.71i)
}

func complex64ToString(c complex64) string {
	return fmt.Sprintf("%v", c) // 输出如: (3.14+2.71i)
}
func stringToComplex128(s string) (complex128, error) {
	var c complex128
	s = strings.TrimSpace(s)

	// 标准格式: (3.14+2.71i)
	n, err := fmt.Sscanf(s, "%v", &c)
	if n == 1 && err == nil {
		return c, nil
	}

	// 尝试无括号格式
	var re, im float64
	n, err = fmt.Sscanf(s, "%f%fi", &re, &im)
	if n == 2 && err == nil {
		return complex(re, im), nil
	}

	// 尝试纯实数
	if r, err := strconv.ParseFloat(s, 64); err == nil {
		return complex(r, 0), nil
	}

	// 尝试纯虚数（如 "3i"）
	if len(s) > 0 && s[len(s)-1] == 'i' {
		imStr := s[:len(s)-1]
		switch imStr {
		case "+":
			im = 1
		case "-":
			im = -1
		default:
			im, err = strconv.ParseFloat(imStr, 64)
			if err != nil {
				return 0, ErrValueUnableToType("string", "complex128, error: invalid imaginary part")
			}
		}
		return complex(0, im), nil
	}

	return 0, ErrValueUnableToType("string", "complex128")
}
func stringToComplex64(s string) (complex64, error) {
	c, err := stringToComplex128(s)
	return complex64(c), err
}
